//
// Created by Administrator on 2024/11/11.
//

#ifndef AI_PACS_DICOMSCHEMA_H
#define AI_PACS_DICOMSCHEMA_H


#include <string>
#include <vector>
#include <optional>
#include <iostream>
#include <unordered_map>
#include <variant>
#include <nlohmann/json.hpp>

// Forward declarations to handle nested types
struct DicomPatient;
struct DicomSeries;
struct DicomInstance;
struct DicomPatient;
struct DcmImage;



// DicomInstance struct
struct DicomInstance {
    std::string bitsAllocated;
    bool bitsSigned;
    std::string bitsStored;
    std::string columns;
    std::string fileName;
    int fileSize;
    std::string highBit;
    std::vector<std::string> imageOrientations;
    std::vector<std::string> imagePositions;
    std::vector<std::string> imageTypes;
    std::string modality;
    std::string number;
    std::string photometricInterpretation;
    std::vector<float> pixelSpacings;
    float rescaleIntercept;
    float rescaleSlop;
    std::string rows;
    std::string sliceThickness;
    std::string uid;
    std::string windowCenter;
    std::string windowWidth;

public:
    NLOHMANN_DEFINE_TYPE_INTRUSIVE(DicomInstance,
                                   bitsAllocated,
                                   bitsSigned,
                                   bitsStored,
                                   columns,
                                   fileName,
                                   fileSize,
                                   highBit,
                                   imageOrientations,
                                   imagePositions,
                                   imageTypes,
                                   modality,
                                   number,
                                   photometricInterpretation,
                                   pixelSpacings,
                                   rescaleIntercept,
                                   rescaleSlop,
                                   rows,
                                   sliceThickness,
                                   uid,
                                   windowCenter,
                                   windowWidth
    )
};



// DicomSeries struct
struct DicomSeries {
    std::string bodyPart;
    std::string date;
    std::string description;
    std::vector<DicomInstance> instances;
    std::string institionName;
    std::string manufacturer;
    std::string manufacturerModelName;
    std::string stationName;
    int number{};
    std::string protocolName;
    std::string time;
    std::string uid;

public:
    NLOHMANN_DEFINE_TYPE_INTRUSIVE(DicomSeries,
                                   bodyPart,
                                   date,
                                   description,
                                   instances,
                                   institionName,
                                   manufacturer,
                                   manufacturerModelName,
                                   stationName,
                                   number,
                                   protocolName,
                                   time,
                                   uid
    )
};

// DicomPatient struct
struct DicomPatient {
    std::string age;
    std::string dateOfBirth;
    std::string gender;
    std::string id;
    std::string name;

    NLOHMANN_DEFINE_TYPE_INTRUSIVE(DicomPatient,age,dateOfBirth,gender,id,name)
};


// DicomStudy struct
struct DicomStudy {
    std::string rootPath;
    std::string bucketName;
    std::string accessionNumber;
    std::string date;
    std::string description;
    std::string id;
    DicomPatient patient;
    std::string pipeline;
    std::vector<DicomSeries> series;
    std::string time;
    std::string uid;
    std::string transferSyntaxUid;
    std::vector<std::string> transferSyntaxUidList;
    std::string modality;
    int storageSize;
    int instanceCount;
    std::string studySearchId;
    std::string srcAet;
    int seriesCount;
    std::string manufacturerModelName;
    std::string stationName;
    std::string examRefId;
    std::string clinicalImpression;
    std::string bodyPart;
    std::string endPoint;
    std::string installCode;

public:
    NLOHMANN_DEFINE_TYPE_INTRUSIVE(DicomStudy,
                                   rootPath,
                                   bucketName,
                                   accessionNumber,
                                   date,
                                   description,
                                   id,
                                   patient,
                                   pipeline,
                                   series,
                                   time,
                                   uid,
                                   transferSyntaxUid,
                                   transferSyntaxUidList,
                                   modality,
                                   storageSize,
                                   instanceCount,
                                   studySearchId,
                                   srcAet,
                                   seriesCount,
                                   manufacturerModelName,
                                   stationName,
                                   examRefId,
                                   clinicalImpression,
                                   bodyPart,
                                   endPoint,
                                   installCode
    )
};



#endif //AI_PACS_DICOMSCHEMA_H
